From 7651defa19abf480166a4d2f4d6c416bf30d0ab8 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Thu, 27 Jul 2006 17:44:14 -0500 Subject: [PATCH] [powerpc] implement per-cpu data areas, based on x86 code Signed-off-by: Hollis Blanchard --- xen/arch/powerpc/Makefile | 3 +++ xen/arch/powerpc/setup.c | 36 +++++++++++++++++++++++++ xen/arch/powerpc/{xen.lds => xen.lds.S} | 13 +++++++++ xen/include/asm-powerpc/percpu.h | 22 +++++++++++++++ 4 files changed, 74 insertions(+) rename xen/arch/powerpc/{xen.lds => xen.lds.S} (96%) create mode 100644 xen/include/asm-powerpc/percpu.h diff --git a/xen/arch/powerpc/Makefile b/xen/arch/powerpc/Makefile index 050d4d82ca..2634acbdf6 100644 --- a/xen/arch/powerpc/Makefile +++ b/xen/arch/powerpc/Makefile @@ -109,6 +109,9 @@ $(TARGET): boot32.o $(TARGET).bin.o asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS) $(CC) $(CFLAGS) -S -o $@ $< +xen.lds: xen.lds.S $(HDRS) + $(CC) $(CFLAGS) -P -E $(AFLAGS) -o $@ $< + dom0.bin: $(DOM0_IMAGE) cp $< $@ diff --git a/xen/arch/powerpc/setup.c b/xen/arch/powerpc/setup.c index 176328c827..dbb4dfe0b8 100644 --- a/xen/arch/powerpc/setup.c +++ b/xen/arch/powerpc/setup.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "exceptions.h" #include "of-devtree.h" @@ -68,6 +69,7 @@ cpumask_t cpu_online_map; /* missing ifdef in schedule.c */ ulong isa_io_base; struct ns16550_defaults ns16550; +extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[]; extern void idle_loop(void); /* move us to a header file */ @@ -117,6 +119,36 @@ static void hw_probe_attn(unsigned char key, struct cpu_user_regs *regs) asm volatile(".long 0x00000200; nop"); } +static void percpu_init_areas(void) +{ + unsigned int i, data_size = __per_cpu_data_end - __per_cpu_start; + + BUG_ON(data_size > PERCPU_SIZE); + + for ( i = 1; i < NR_CPUS; i++ ) + memcpy(__per_cpu_start + (i << PERCPU_SHIFT), + __per_cpu_start, + data_size); +} + +static void percpu_free_unused_areas(void) +{ + unsigned int i, first_unused; + + /* Find first unused CPU number. */ + for ( i = 0; i < NR_CPUS; i++ ) + if ( !cpu_online(i) ) + break; + first_unused = i; + + /* Check that there are no holes in cpu_online_map. */ + for ( ; i < NR_CPUS; i++ ) + BUG_ON(cpu_online(i)); + + init_xenheap_pages((ulong)__per_cpu_start + (first_unused << PERCPU_SHIFT), + (ulong)__per_cpu_end); +} + static void __init start_of_day(void) { struct domain *idle_domain; @@ -135,6 +167,8 @@ static void __init start_of_day(void) /* for some reason we need to set our own bit in the thread map */ cpu_set(0, cpu_sibling_map[0]); + percpu_free_unused_areas(); + initialize_keytable(); /* Register another key that will allow for the the Harware Probe * to be contacted, this works with RiscWatch probes and should @@ -265,6 +299,8 @@ static void __init __start_xen(multiboot_info_t *mbi) ofd_walk((void *)oftree, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL); #endif + percpu_init_areas(); + /* mark all memory from modules onward as unused */ init_boot_pages(freemem, eomem); diff --git a/xen/arch/powerpc/xen.lds b/xen/arch/powerpc/xen.lds.S similarity index 96% rename from xen/arch/powerpc/xen.lds rename to xen/arch/powerpc/xen.lds.S index b4ac9c48a6..9449bc9aba 100644 --- a/xen/arch/powerpc/xen.lds +++ b/xen/arch/powerpc/xen.lds.S @@ -1,3 +1,7 @@ +#include +#include +#include + /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc") @@ -104,6 +108,7 @@ SECTIONS } /* Xen addition */ + . = ALIGN(32); __setup_start = .; .setup.init : { *(.setup.init) } @@ -114,6 +119,14 @@ SECTIONS __inithcall_start = .; .inithcall.text : { *(.inithcall.text) } __inithcall_end = .; + + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } :text + __per_cpu_data_end = .; + . = __per_cpu_start + (NR_CPUS << PERCPU_SHIFT); + . = ALIGN(STACK_SIZE); + __per_cpu_end = .; + /* end Xen addition */ .data1 : { *(.data1) } diff --git a/xen/include/asm-powerpc/percpu.h b/xen/include/asm-powerpc/percpu.h new file mode 100644 index 0000000000..59d62d64a7 --- /dev/null +++ b/xen/include/asm-powerpc/percpu.h @@ -0,0 +1,22 @@ +/* from xen/include/asm-x86/percpu.h */ + +#ifndef __PPC_PERCPU_H__ +#define __PPC_PERCPU_H__ + +#define PERCPU_SHIFT 12 +#define PERCPU_SIZE (1UL << PERCPU_SHIFT) + +/* Separate out the type, so (int[3], foo) works. */ +#define DEFINE_PER_CPU(type, name) \ + __attribute__((__section__(".data.percpu"))) \ + __typeof__(type) per_cpu__##name + +/* var is in discarded region: offset to particular copy we want */ +#define per_cpu(var, cpu) \ + (*RELOC_HIDE(&per_cpu__##var, ((unsigned int)(cpu))<